package com.pizzaria.servlet;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;

import br.com.dk.database.Register;

import com.pizzaria.bean.Cliente;
import com.pizzaria.bean.ClienteDAO;
import com.pizzaria.bean.Funcionario;
import com.pizzaria.bean.FuncionarioDAO;
import com.pizzaria.bean.Pedido;
import com.pizzaria.bean.PedidoDAO;
import com.pizzaria.bean.PedidoProduto;
import com.pizzaria.bean.PedidoProdutoDAO;
import com.pizzaria.bean.Produto;
import com.pizzaria.bean.ProdutoDAO;
import com.pizzaria.util.Util;
import com.sun.jersey.api.client.ClientResponse.Status;

@Path("/crud")
public class CrudResource {
	public class UnauthorizedException extends WebApplicationException {

	     public UnauthorizedException() {
	         super(Response.status(Status.UNAUTHORIZED).build());
	     }

	     public UnauthorizedException(String message) {
	         super(Response.status(Status.UNAUTHORIZED).entity(message).type("text/plain").build());
	     }

	}
	
	@Path("/cliente")
	@POST
	@Produces("text/html;charset=ISO-8859-1")
	public String clienteNU(@FormParam("txtCod") @DefaultValue("0") long id, @FormParam("txtNome") String nome, @FormParam("txtCPF") String cpf,
			@FormParam("txtNasc") String nasc, @FormParam("txtTel") String tel, @FormParam("txtCel") String cel, @FormParam("txtOperadora") String operadora,
			@FormParam("txtEnd") String endereco, @FormParam("txtNum") String num, @FormParam("txtComp") String comp, @FormParam("txtCEP") String cep, @FormParam("txtCidade") String cidade){
		Cliente cli = null;
		Date dtNasc = Util.parseDate(nasc);
		
		Register<Cliente> reg = new Register<Cliente>(Cliente.class);
		if(id == 0) {
			Cliente f = ClienteDAO.getByCpf(cpf);
			if(f != null){
				throw new UnauthorizedException("Erro CPF, já cadastrado.");
			}
		}
		
		cli = new Cliente(id, nome, cpf, dtNasc, tel, cel, operadora, endereco, num, comp, cidade, cep);
		if(cli.getId() > 0)
			reg.update(cli);
		else
			reg.insert(cli);
		return "Salvo com sucesso.";
	}
	
	@Path("/funcionario")
	@POST
	@Produces("text/html;charset=ISO-8859-1")
	public String funcionarioNU(@FormParam("txtCod") @DefaultValue("0") long id, @FormParam("txtNome") String nome, @FormParam("txtCPF") String cpf, @FormParam("txtRG") String rg,
			@FormParam("txtNasc") String nasc, @FormParam("txtTel") String tel, @FormParam("txtCel") String cel,
			@FormParam("txtEnd") String endereco, @FormParam("txtNum") String num, @FormParam("txtComp") String comp, @FormParam("txtCEP") String cep, 
			@FormParam("txtCidade") String cidade, @FormParam("txtCargo") String cargo, @FormParam("txtSal") String salario){
		Funcionario o = null;
		Date dtNasc = Util.parseDate(nasc);
		
		Register<Funcionario> reg = new Register<Funcionario>(Funcionario.class);
		if(id == 0) {
			Funcionario f = FuncionarioDAO.getByCpf(cpf);
			if(f != null){
				throw new UnauthorizedException("Erro CPF, já cadastrado.");
			}
		}
		o = new Funcionario(id, nome, rg, cpf, dtNasc, tel, cel, endereco, num, comp, cep, cidade, cargo, Util.parseFloat(salario));
		System.out.println(o);
		try{
			if(o.getId() > 0)
				reg.update(o);
			else
				reg.insert(o);
		} catch(RuntimeException e){
			e.printStackTrace();
			return "ERRO " + e.getMessage();
		}
		System.out.println(o.getSalario());
		return "Salvo com sucesso.";
	}
	
	@Path("/produto")
	@POST
	@Produces("text/html;charset=ISO-8859-1")
	public String produtoNU(@FormParam("txtCod") @DefaultValue("0") long id, @FormParam("txtTipo") byte tipo, @FormParam("txtNomeProduto") String nome,
			@FormParam("txtQtd") @DefaultValue("0") String qtd, @FormParam("txtValid") String validade, @FormParam("txtValor") String valor, @FormParam("txtDesc") String desc){
		Produto o = null;
		Date dtValidade = null;
		if(validade != null && !validade.isEmpty()) dtValidade = Util.parseDate(validade);
		
		Register<Produto> reg = new Register<Produto>(Produto.class);
		o = new Produto(id, nome, Util.parseFloat(valor), dtValidade, Util.parseFloat(qtd), desc, tipo);
		try{
			if(o.getId() > 0)
				reg.update(o);
			else
				reg.insert(o);
		} catch(RuntimeException e){
			e.printStackTrace();
			return "ERRO " + e.getMessage();
		}
		return "Salvo com sucesso.";
	}
	
	@Path("/pedido")
	@POST
	@Produces("text/html;charset=ISO-8859-1")
	public String pedidoNU(@FormParam("txtCod") @DefaultValue("0") long id, @FormParam("txtCli") long cliId, @FormParam("prod") List<String> prods, @FormParam("qtd") List<String> qtd, @FormParam("fechado") @DefaultValue("false") boolean fechado, @FormParam("endereco") String endereco, @FormParam("vlpago") String vlpago, @FormParam("vlentrega") String vlentrega, @FormParam("observacao") String obs, @FormParam("entregue") @DefaultValue("false") boolean entregue){
		Register<Pedido> reg = new Register<Pedido>(Pedido.class, true);
		Register<PedidoProduto> regProdPed = new Register<PedidoProduto>(PedidoProduto.class, true);
		Register<Produto> regProd = new Register<Produto>(Produto.class, true);
		reg.shareConnection(regProd);
		reg.shareConnection(regProdPed);
		Pedido p = null;
		
		if(id == 0){
			Cliente c = new Cliente();
			c.setId(cliId);
			p = new Pedido(id, c, Calendar.getInstance().getTime(), 0, fechado, endereco, Util.parseFloat(vlpago), Util.parseFloat(vlentrega), obs, entregue);
			reg.insert(p);
			
			int i = 0;
			float total = 0;
			for(String prod : prods){
				int q = Integer.parseInt(qtd.get(i));
				i++;
				if(q == 0) continue;
				
				Produto pp = ProdutoDAO.get(Long.parseLong(prod));
				total += pp.getValor() * q;
				regProdPed.insert(new PedidoProduto(0, p, pp, q, pp.getValor()));
				if(pp.getQtdEstoque() > 0 && pp.getQtdEstoque() >= q){
					pp.setQtdEstoque(pp.getQtdEstoque() - q);
					regProd.update(pp);
				}
			}
			if(fechado) {
				p.setTotal(total + p.getVlEntrega());
				reg.update(p);
			}
			reg.commit();
			reg.close();
		} else {
			p = PedidoDAO.get(id);
			List<PedidoProduto> pprods = PedidoProdutoDAO.getByPedido(p);
			p.setFechado(fechado);
			p.setEndereco(endereco);
			p.setObservacao(obs);
			p.setVlPago(Util.parseFloat(vlpago));
			p.setVlEntrega(Util.parseFloat(vlentrega));
			p.setEntregue(entregue);
			
			int i = 0;
			float total = 0;
			up: for(String sprod : prods){
				long prod = Long.parseLong(sprod);
				int q = Integer.parseInt(qtd.get(i));
				i++;
				if(q == 0) continue;
				
				for(PedidoProduto pp : pprods){
					if(pp.getProduto().getId() == prod) {
						int removeQtd = q - pp.getQuantidade();
						if(removeQtd == 0) {
							continue up;
						}
						
						Produto py = pp.getProduto();
						pp.setQuantidade(q);
//						pp.setValor(pp.getValor() + (py.getValor() * removeQtd));
						pp.setValor(pp.getValor());//+ (py.getValor() * removeQtd)
						regProdPed.update(pp);
						
						if(py.getQtdEstoque() > 0 && py.getQtdEstoque() >= removeQtd){
							py.setQtdEstoque(py.getQtdEstoque() - removeQtd);
							regProd.update(py);
						}
						continue up;
					}
				}
				
				Produto pp = ProdutoDAO.get(prod);
				total += pp.getValor() * q;
				regProdPed.insert(new PedidoProduto(0, p, pp, q, pp.getValor() * q));
				if(pp.getQtdEstoque() > 0 && pp.getQtdEstoque() >= q){
					pp.setQtdEstoque(pp.getQtdEstoque() - q);
					regProd.update(pp);
				}
			}
			
			for(PedidoProduto pp : pprods){
				total += pp.getValor() * pp.getQuantidade();
			}
			
			if(fechado) {
				p.setTotal(total + p.getVlEntrega());
			}
			reg.update(p);
			reg.commit();
			reg.close();
		}
		return p.getId() + "";
	}
	
	@Path("/delete")
	@POST
	@Produces("text/html;charset=ISO-8859-1")
	public String delete(@FormParam("type") String type, @FormParam("id") List<String> ids){
		switch (type.hashCode()) {
		case 3449687: //produto
			Register<Produto> prod = new Register<Produto>(Produto.class, true);
			for(String i : ids) prod.deleteById(Long.parseLong(i));
			prod.commit(); prod.close();
			break;
		case 98592: //cliente
			Register<Cliente> cli = new Register<Cliente>(Cliente.class, true);
			for(String i : ids) cli.deleteById(Long.parseLong(i));
			cli.commit(); cli.close();
			break;
		case 3154628: //funcionario
			Register<Funcionario> func = new Register<Funcionario>(Funcionario.class, true);
			for(String i : ids) func.deleteById(Long.parseLong(i));
			func.commit(); func.close();
			break;
		case 110863: //pedido
			Register<Pedido> ped = new Register<Pedido>(Pedido.class, true);
			Register<PedidoProduto> prodPed = new Register<PedidoProduto>(PedidoProduto.class, true);
			ped.shareConnection(prodPed);
			for(String i : ids) {
				long id = Long.parseLong(i);
				ped.deleteById(id);
			}
			ped.commit(); ped.close();
			break;
		}
		return "Deletado com sucesso.";
	}
	
	@Path("/init")
	@GET
	@Produces("text/html;charset=ISO-8859-1")
	public String init(){
		if(ProdutoDAO.getAll().size() > 0) return "Já iniciado";
		
		Register<Produto> regProd = new Register<Produto>(Produto.class, true);
		regProd.insert(new Produto(0, "Coca-Cola", 5.6f, null, 0, "", (byte)1));
		regProd.insert(new Produto(0, "Pizza Marguerita", 23.6f, null, 0, "", (byte)2));
		regProd.insert(new Produto(0, "Pizza Portugueza", 25.6f, null, 0, "", (byte)2));
		regProd.insert(new Produto(0, "Pizza Muzzarela", 18.2f, null, 0, "", (byte)2));
		regProd.insert(new Produto(0, "Sprite", 4.5f, null, 0, "", (byte)1));
		regProd.insert(new Produto(0, "Dose Rum", 5.0f, null, 0, "", (byte)1));
		regProd.commit();regProd.close();
		Register<Funcionario> regFunc = new Register<Funcionario>(Funcionario.class, true);
		regFunc.insert(new Funcionario(0, "João das Neves", "33.446.678-2", "777.777.777-1", new Date(1977, 02, 14), 
				"(13) 4566-8902", "", "Rua Augusta", "69", "", "11345-678", "São Paulo", "Barman", 1200.10f));
		regFunc.insert(new Funcionario(0, "Efesto Adams", "33.446.677-2", "777.777.771-1", new Date(1710, 03, 20), 
				"(13) 4566-8902", "", "Rua Augusta", "69", "", "11345-678", "São Paulo", "Garçom I", 900.10f));
		regFunc.insert(new Funcionario(0, "Morticia Adams", "33.446.568-2", "777.777.712-1", new Date(1890, 11, 25), 
				"(13) 4566-8902", "", "Rua Augusta", "69", "", "11345-678", "São Paulo", "Garçom II", 1050.10f));
		regFunc.commit(); regFunc.close();
		Register<Cliente> regCli = new Register<Cliente>(Cliente.class, true);
		regCli.insert(new Cliente(0, "Alfredo Victor", "777.777.512-1", new Date(1950, 11, 25), 
				"(13) 4566-8902", "", "","Rua Augusta", "69", "", "São Paulo", "11345-678"));
		regCli.insert(new Cliente(0, "Cícero Antônio", "777.777.612-2", new Date(1980, 7, 18), 
				"(13) 4566-8902", "", "","Rua Domino", "69", "", "São Paulo", "11345-678"));
		regCli.insert(new Cliente(0, "Gomes Adams", "777.889.612-2", new Date(1790, 8, 22), 
				"(13) 4566-8902", "", "","Rua Xadrez", "69", "", "São Paulo", "11345-678"));
		regCli.commit(); regCli.close();
		
		return "INICIADO";
	}
}
